#ifndef REMOTECLIENT_H
#define REMOTECLIENT_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QUdpSocket>
#include <QLabel>
#include <QBoxLayout>
#include <QMouseEvent>
#include <QApplication>
#include <QElapsedTimer>
#include <QDebug>

#define CONTROL_PORT 8888
#define VIDEO_PORT 8889
#define KEY_AUTH 0x01
#define KEY_MOUSE_MOVE 0x11
#define KEY_MOUSE_CLICK 0x12
#define KEY_MOUSE_WHEEL 0x13
#define KEY_KEYBOARD 0x10
#define KEY_FRAME_REQUEST 0x30

//#define CONTROL_PORT 8888
//#define VIDEO_PORT 8889

#include <QNetworkDatagram>
#include <QPixmap>
class RemoteClient : public QMainWindow {
    Q_OBJECT
public:
    RemoteClient(QWidget *parent = nullptr) : QMainWindow(parent) {
        tcpSocket = new QTcpSocket(this);
        udpSocket = new QUdpSocket(this);

        setupUI();
        setupConnections();
    }

    void connectToHost(const QString &host, quint16 port = CONTROL_PORT) {
        tcpSocket->connectToHost(host, port);
        udpSocket->bind(VIDEO_PORT);
    }

private:
    void setupUI() {
        QWidget *central = new QWidget;
        QVBoxLayout *layout = new QVBoxLayout(central);

        screenLabel = new QLabel;
        screenLabel->setAlignment(Qt::AlignCenter);
        screenLabel->setMinimumSize(640, 480);
        screenLabel->installEventFilter(this);

        layout->addWidget(screenLabel);
        setCentralWidget(central);
        resize(1024, 768);
        setWindowTitle("Linux Remote Desktop Client");
    }

    void setupConnections() {
        connect(tcpSocket, &QTcpSocket::connected, this, [=]() {
            qInfo() << "Connected to server";
            sendAuthentication();
            connect(udpSocket, &QUdpSocket::readyRead, this, &RemoteClient::readVideoData);
        });

        connect(tcpSocket, &QTcpSocket::readyRead, this, &RemoteClient::readControlData);
        connect(tcpSocket, &QTcpSocket::disconnected, this, [=]() {
            qInfo() << "Disconnected from server";
            udpSocket->close();
        });
    }

    void sendAuthentication() {
        QByteArray data;
        data.append(KEY_AUTH);
        data.append("PASS"); // 4-byte password
        tcpSocket->write(data);
    }

    void requestFrame() {
        tcpSocket->write(QByteArray(1, KEY_FRAME_REQUEST));
    }

    void readControlData() {
        // 预留控制信令处理
    }

    void readVideoData() {
        while (udpSocket->hasPendingDatagrams()) {
            QNetworkDatagram datagram = udpSocket->receiveDatagram();
            QByteArray data = datagram.data();

            QDataStream stream(data);
            quint16 frameHeader;
            stream >> frameHeader;

            if (frameHeader != 0xFF01) // 仅处理关键帧
                continue;

            quint32 frameId;
            quint16 fragments;
            quint16 fragmentIndex;
            QByteArray jpegData;

            stream >> frameId >> fragments >> fragmentIndex >> jpegData;

            // 帧组装（简单实现，未处理乱序）
            if (fragmentIndex == 0) {
                currentFrameData = jpegData;qDebug()<<"start";
            } else {
                currentFrameData.append(jpegData);
            }

            // 最后一帧片段
            if (fragmentIndex == fragments - 1) {
                QImage image;static int index = 0;
                image.loadFromData(currentFrameData, "JPEG");qDebug()<<"接受图片成功"<<index++;

                if (!image.isNull()) {
                    QPixmap pixmap = QPixmap::fromImage(image);
                    screenLabel->setPixmap(pixmap.scaled(
                        screenLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));

                    // 计算帧率
                    qint64 elapsed = frameTimer.elapsed();
                    if (elapsed > 0) {
                        double fps = 1000.0 / elapsed;
                        setWindowTitle(QString("Remote Desktop - FPS: %1").arg(fps, 0, 'f', 1));
                    }
                    frameTimer.restart();
                }
            }
        }
    }

//    bool eventFilter(QObject *watched, QEvent *event) override {
//        if (watched == screenLabel && tcpSocket->state() == QTcpSocket::ConnectedState) {
//            if (event->type() == QEvent::MouseMove) {
//                QMouseEvent *me = static_cast<QMouseEvent*>(event);
//                QPoint pos = me->pos();
//                QSize size = screenLabel->size();
//                QPixmap pixmap = *screenLabel->pixmap();

//                if (pixmap.isNull()) return false;

//                // 转换为远程坐标
//                double scaleX = static_cast<double>(remoteResolution.width()) / pixmap.width();
//                double scaleY = static_cast<double>(remoteResolution.height()) / pixmap.height();
//                qint16 remoteX = static_cast<qint16>(pos.x() * scaleX);
//                qint16 remoteY = static_cast<qint16>(pos.y() * scaleY);

//                sendMouseMove(remoteX, remoteY);
//                return true;
//            }
//            else if (event->type() == QEvent::MouseButtonPress ||
//                     event->type() == QEvent::MouseButtonRelease) {
//                QMouseEvent *me = static_cast<QMouseEvent*>(event);
//                quint8 buttons = 0;
//                if (me->buttons() & Qt::LeftButton) buttons |= 0x01;
//                if (me->buttons() & Qt::RightButton) buttons |= 0x02;

//                sendMouseClick(buttons);
//                return true;
//            }
//        }
//        return QObject::eventFilter(watched, event);
//    }

    void sendMouseMove(qint16 x, qint16 y) {
        QByteArray data;
        data.append(KEY_MOUSE_MOVE);
        data.append(reinterpret_cast<const char*>(&x), 2);
        data.append(reinterpret_cast<const char*>(&y), 2);
        tcpSocket->write(data);
    }

    void sendMouseClick(quint8 buttons) {
        QByteArray data;
        data.append(KEY_MOUSE_CLICK);
        data.append(reinterpret_cast<const char*>(&buttons), 1);
        tcpSocket->write(data);
    }

private:
    QTcpSocket *tcpSocket;
    QUdpSocket *udpSocket;
    QLabel *screenLabel;

    // Video streaming
    QByteArray currentFrameData;
    QElapsedTimer frameTimer;
    QSize remoteResolution;
};



#endif // REMOTECLIENT_H
